package com.yuong.demo.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 〈自定义水平滑动柱状图〉
 *
 * @author yuandong
 * @create 2021/4/22
 * @since 1.0.0
 */
public class HorizontalBarChartView extends View {
    private int width;
    private int height;
    private float histogramInterval;//直方图间距
    private float histogramWidth;//直方图宽度
    private float coordinateAxisWidth;// 坐标轴线宽度
    private float coordinateTitleSize;// 坐标轴线标题文字大小
    private float coordinateXTitleWidth;// 坐标x轴线标题文字的宽度
    private float coordinateXTitleHeight;// 坐标x轴线标题文字的高度
    private float histogramPaddingStart;//直方图左边距
    private float histogramPaddingEnd;//直方图右边距

    private Paint coordinateTitlePaint;//坐标轴线标题画笔
    private TextPaint coordinateXTitlePaint;//X坐标轴线标题画笔
    private Paint.FontMetrics coordinateTitleFontMetrics;
    private float yCoordinateTitleMaxWidth;

    private float xCoordinateLength, yCoordinateLength;//x坐标轴长度，y坐标轴长度

    private float chartPaddingTop;//图表顶部内边距
    private float distanceXCoordinateTitleToAxis;
    private float distanceYCoordinateTitleToAxis;

    private Paint coordinateLinePaint;//坐标轴线画笔
    private Paint whitePaint;//坐标轴线画笔
    private Paint histogramPaint;//直方图画笔
    private float histogramContentWidth;
    private float factor = 0.75f;


    private String[] xTitles = {"大运", "南山", "佛山", "罗湖网球", "贵港", "崇左", "柳州", "武汉", "南通", "长沙", "成都", "苏州", "南京", "上海", "合肥"};
    private String[] YTitles = {"300", "250", "200", "150", "100", "50", "0"};
    private int[] values = {50, 100, 150, 200, 250, 150, 200, 250, 100, 50, 100, 280, 270, 260, 250};
    private int[] colors = new int[]{Color.parseColor("#FFE8B6ED"), Color.parseColor("#FF92D1FF")};
    private float scrollX;//水平滑动距离
    private float lastX;

    public HorizontalBarChartView(Context context) {
        this(context, null);
    }

    public HorizontalBarChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public HorizontalBarChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        chartPaddingTop = dp2px(getContext(), 20);
        coordinateAxisWidth = dp2px(getContext(), 1);
        distanceXCoordinateTitleToAxis = dp2px(getContext(), 10);
        distanceYCoordinateTitleToAxis = dp2px(getContext(), 10);
        histogramInterval = dp2px(getContext(), 24);
        histogramWidth = dp2px(getContext(), 11);
        histogramPaddingStart = dp2px(getContext(), 10);
        histogramPaddingEnd = dp2px(getContext(), 10);

        coordinateXTitleWidth = dp2px(getContext(), 25);
        coordinateXTitleHeight = dp2px(getContext(), 40);
        coordinateTitleSize = sp2px(getContext(), 11);

        coordinateTitlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coordinateTitlePaint.setTextSize(coordinateTitleSize);
        coordinateTitlePaint.setColor(Color.parseColor("#666666"));
        coordinateTitleFontMetrics = coordinateTitlePaint.getFontMetrics();

        coordinateXTitlePaint = new TextPaint();
        coordinateXTitlePaint.setColor(Color.parseColor("#666666"));
        coordinateXTitlePaint.setTextSize(coordinateTitleSize);
        coordinateXTitlePaint.setAntiAlias(true);

        coordinateLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coordinateLinePaint.setStyle(Paint.Style.FILL);
        coordinateLinePaint.setStrokeWidth(coordinateAxisWidth);
        coordinateLinePaint.setColor(Color.parseColor("#FFE9E9E9"));

        histogramPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        histogramPaint.setStyle(Paint.Style.FILL);
        histogramPaint.setStrokeWidth(histogramWidth);

        whitePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        whitePaint.setStyle(Paint.Style.FILL);
        whitePaint.setColor(Color.WHITE);

        yCoordinateTitleMaxWidth = coordinateTitlePaint.measureText("300");

        calculate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);

        xCoordinateLength = width - yCoordinateTitleMaxWidth - distanceYCoordinateTitleToAxis - 2 * coordinateAxisWidth;
//        yCoordinateLength = height - coordinateTitleSize - distanceXCoordinateTitleToAxis - chartPaddingTop;
        yCoordinateLength = height - coordinateXTitleHeight - distanceXCoordinateTitleToAxis - chartPaddingTop;

//        float maxScrollX = histogramContentWidth - width - yCoordinateTitleMaxWidth - distanceYCoordinateTitleToAxis;
//        float maxScrollX = histogramContentWidth - xCoordinateLength;
//        Log.e("****", "maxScrollX : " + maxScrollX);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float yInterval = (yCoordinateLength - 7 * coordinateAxisWidth) / 6f;
        float yOffset = chartPaddingTop;
        for (int i = 0; i < 7; i++) {
            float y = yOffset + (2 * i + 1) * coordinateAxisWidth / 2f + +yInterval * i;
            float startX = yCoordinateTitleMaxWidth + distanceYCoordinateTitleToAxis;
            float endX = width;
            //绘制横向直线
            canvas.drawLine(startX, y, endX, y, coordinateLinePaint);
        }

        //绘制纵向直线
        float startX = yCoordinateTitleMaxWidth + distanceYCoordinateTitleToAxis + coordinateAxisWidth / 2f;
        float startY = chartPaddingTop + coordinateAxisWidth;
        float endY = chartPaddingTop + yCoordinateLength;
        canvas.drawLine(startX, startY, startX, endY, coordinateLinePaint);
        startX = width - coordinateAxisWidth / 2f;
        canvas.drawLine(startX, startY, startX, endY, coordinateLinePaint);

        //绘制x轴标题
        coordinateTitlePaint.setTextAlign(Paint.Align.CENTER);
        float xOffset = yCoordinateTitleMaxWidth + distanceYCoordinateTitleToAxis + coordinateAxisWidth + histogramPaddingStart + scrollX;
//        for (int i = 0; i < xTitles.length; i++) {
//            String title = xTitles[i];
//            coordinateTitlePaint.measureText(title);
//            float titleX = xOffset + (2 * i + 1) * histogramWidth * 0.5f + i * histogramInterval;
//            float titleY = (height - coordinateTitleFontMetrics.bottom / 2);
//            canvas.drawText(title, titleX, titleY, coordinateTitlePaint);
//        }

        for (int i = 0; i < xTitles.length; i++) {
            String title = xTitles[i];
            coordinateTitlePaint.measureText(title);
            float titleX = xOffset + (2 * i + 1) * histogramWidth * 0.5f + i * histogramInterval;
            float titleY = height - coordinateXTitleHeight;
            StaticLayout layout = new StaticLayout(title, coordinateXTitlePaint, (int)coordinateXTitleWidth,
                    Layout.Alignment.ALIGN_CENTER, 1.0F, 0.0F, true);
            //int height = layout.getHeight();
            //Log.e("**********", "height : " + height);
            canvas.save();
            canvas.translate(titleX - coordinateXTitleWidth * 0.5f, titleY);
            layout.draw(canvas);
            canvas.restore();
        }

        //画直方图
        for (int i = 0; i < values.length; i++) {
            int value = values[i];
            float titleHeight = value * yCoordinateLength / 300f;
            float titleX = xOffset + +(2 * i + 1) * histogramWidth * 0.5f + i * histogramInterval;
            float titleStartY = chartPaddingTop + yCoordinateLength;
            float titleEndY = titleStartY - titleHeight;
            LinearGradient shader = new LinearGradient(titleX, titleStartY, titleX, titleEndY, colors, null, Shader.TileMode.CLAMP);
            histogramPaint.setShader(shader);
            canvas.drawLine(titleX, titleStartY, titleX, titleEndY, histogramPaint);
        }

        whitePaint.setStrokeWidth(yCoordinateTitleMaxWidth + distanceYCoordinateTitleToAxis);
        float whiteX = (yCoordinateTitleMaxWidth + distanceYCoordinateTitleToAxis) / 2f;
        canvas.drawLine(whiteX, 0, whiteX, height, whitePaint);

        //画y轴标题
        coordinateTitlePaint.setTextAlign(Paint.Align.RIGHT);
        for (int i = 0; i < YTitles.length; i++) {
            String title = YTitles[i];
            coordinateTitlePaint.measureText(title);
            float x = yCoordinateTitleMaxWidth;
            float y = yOffset + (2 * i + 1) * coordinateAxisWidth / 2f + +yInterval * i;
            //绘制横向直线
            canvas.drawText(title, x, y + coordinateTitleSize / 2f, coordinateTitlePaint);
        }
    }

    //计算直方图总宽度
    private void calculate() {
        if (values != null && values.length > 0) {
            histogramContentWidth = values.length * histogramWidth + (values.length - 1) * histogramInterval;
        }
    }

    /**
     * 判断是否可以水平滑动
     *
     * @return @param direction 标识滑动方向  正数：右滑(手指从右至左移动)；负数：左滑(手指由左向右移动)
     */
    @Override
    public boolean canScrollHorizontally(int direction) {
        if (direction > 0) {
            return histogramContentWidth + histogramPaddingStart + histogramPaddingEnd - xCoordinateLength - Math.abs(scrollX) > 0;
        } else {
            return scrollX < 0;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float currentX = event.getX();
                float offset = currentX - lastX;
                if (offset < 0) {//右滑
                    if (canScrollHorizontally(1)) {
                        scrollX += offset * factor;
                        Log.e("****", "scrollX : " + scrollX);
                        if (Math.abs(scrollX) >= histogramContentWidth - xCoordinateLength + histogramPaddingStart + histogramPaddingEnd) {
                            scrollX = -(histogramContentWidth - xCoordinateLength + histogramPaddingStart + histogramPaddingEnd);
                        }
                        Log.e("****", "scrollX2 : " + scrollX);
                        postInvalidate();
                    }
                }

                if (offset > 0) {//左滑
                    if (canScrollHorizontally(-1)) {
                        scrollX += offset * factor;
                        if (scrollX >= 0) {
                            scrollX = 0;
                        }
                        postInvalidate();
                    }
                }
                lastX = currentX;
                break;
            case MotionEvent.ACTION_UP:
                lastX = 0;
                break;
        }
        return true;
    }


    /**
     * dp转px
     */
    public static float dp2px(Context context, float dpVal) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, context.getResources().getDisplayMetrics());
    }

    /**
     * sp转px
     */
    public static float sp2px(Context context, float spVal) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, context.getResources().getDisplayMetrics());
    }
}